using System;

namespace OracleInternal.Secure.Network
{
	public class DES168 : EncryptionAlgorithm
	{
		internal new const int field_a = 8;

		internal const int field_b = 1;

		internal const int field_c = 2;

		internal const byte field_d = 0;

		internal const byte field_e = 1;

		internal byte[] field_f = new byte[8];

		internal byte[] field_g = new byte[8];

		internal byte[] field_h = new byte[8];

		private uint[] field_i;

		private uint[] field_j;

		private uint[] field_k;

		private uint[] field_l;

		private uint[] field_m;

		private uint[] field_n;

		private byte[] field_o = new byte[8];

		internal bool field_p;

		private static short[] field_q = new short[8]
		{
			200,
			100,
			40,
			20,
			10,
			4,
			2,
			1
		};

		private static uint[] field_r = new uint[24]
		{
			8388608u,
			4194304u,
			2097152u,
			1048576u,
			524288u,
			262144u,
			131072u,
			65536u,
			32768u,
			16384u,
			8192u,
			4096u,
			2048u,
			1024u,
			512u,
			256u,
			128u,
			64u,
			32u,
			16u,
			8u,
			4u,
			2u,
			1u
		};

		private static uint[] s = new uint[24]
		{
			8388608u,
			4194304u,
			2097152u,
			1048576u,
			524288u,
			262144u,
			131072u,
			65536u,
			32768u,
			16384u,
			8192u,
			4096u,
			2048u,
			1024u,
			512u,
			256u,
			128u,
			64u,
			32u,
			16u,
			8u,
			4u,
			2u,
			1u
		};

		private static byte[] t = new byte[56]
		{
			56,
			48,
			40,
			32,
			24,
			16,
			8,
			0,
			57,
			49,
			41,
			33,
			25,
			17,
			9,
			1,
			58,
			50,
			42,
			34,
			26,
			18,
			10,
			2,
			59,
			51,
			43,
			35,
			62,
			54,
			46,
			38,
			30,
			22,
			14,
			6,
			61,
			53,
			45,
			37,
			29,
			21,
			13,
			5,
			60,
			52,
			44,
			36,
			28,
			20,
			12,
			4,
			27,
			19,
			11,
			3
		};

		private static byte[] u = new byte[16]
		{
			1,
			2,
			4,
			6,
			8,
			10,
			12,
			14,
			15,
			17,
			19,
			21,
			23,
			25,
			27,
			28
		};

		private static byte[] v = new byte[48]
		{
			13,
			16,
			10,
			23,
			0,
			4,
			2,
			27,
			14,
			5,
			20,
			9,
			22,
			18,
			11,
			3,
			25,
			7,
			15,
			6,
			26,
			19,
			12,
			1,
			40,
			51,
			30,
			36,
			46,
			54,
			29,
			39,
			50,
			44,
			32,
			47,
			43,
			48,
			38,
			55,
			33,
			52,
			45,
			41,
			49,
			35,
			28,
			31
		};

		private static byte[] w = new byte[8]
		{
			1,
			35,
			69,
			103,
			137,
			171,
			205,
			239
		};

		private static uint[] x = new uint[64]
		{
			16843776u,
			0u,
			65536u,
			16843780u,
			16842756u,
			66564u,
			4u,
			65536u,
			1024u,
			16843776u,
			16843780u,
			1024u,
			16778244u,
			16842756u,
			16777216u,
			4u,
			1028u,
			16778240u,
			16778240u,
			66560u,
			66560u,
			16842752u,
			16842752u,
			16778244u,
			65540u,
			16777220u,
			16777220u,
			65540u,
			0u,
			1028u,
			66564u,
			16777216u,
			65536u,
			16843780u,
			4u,
			16842752u,
			16843776u,
			16777216u,
			16777216u,
			1024u,
			16842756u,
			65536u,
			66560u,
			16777220u,
			1024u,
			4u,
			16778244u,
			66564u,
			16843780u,
			65540u,
			16842752u,
			16778244u,
			16777220u,
			1028u,
			66564u,
			16843776u,
			1028u,
			16778240u,
			16778240u,
			0u,
			65540u,
			66560u,
			0u,
			16842756u
		};

		private static uint[] y = new uint[64]
		{
			2148565024u,
			2147516416u,
			32768u,
			1081376u,
			1048576u,
			32u,
			2148532256u,
			2147516448u,
			2147483680u,
			2148565024u,
			2148564992u,
			2147483648u,
			2147516416u,
			1048576u,
			32u,
			2148532256u,
			1081344u,
			1048608u,
			2147516448u,
			0u,
			2147483648u,
			32768u,
			1081376u,
			2148532224u,
			1048608u,
			2147483680u,
			0u,
			1081344u,
			32800u,
			2148564992u,
			2148532224u,
			32800u,
			0u,
			1081376u,
			2148532256u,
			1048576u,
			2147516448u,
			2148532224u,
			2148564992u,
			32768u,
			2148532224u,
			2147516416u,
			32u,
			2148565024u,
			1081376u,
			32u,
			32768u,
			2147483648u,
			32800u,
			2148564992u,
			1048576u,
			2147483680u,
			1048608u,
			2147516448u,
			2147483680u,
			1048608u,
			1081344u,
			0u,
			2147516416u,
			32800u,
			2147483648u,
			2148532256u,
			2148565024u,
			1081344u
		};

		private static uint[] z = new uint[64]
		{
			520u,
			134349312u,
			0u,
			134348808u,
			134218240u,
			0u,
			131592u,
			134218240u,
			131080u,
			134217736u,
			134217736u,
			131072u,
			134349320u,
			131080u,
			134348800u,
			520u,
			134217728u,
			8u,
			134349312u,
			512u,
			131584u,
			134348800u,
			134348808u,
			131592u,
			134218248u,
			131584u,
			131072u,
			134218248u,
			8u,
			134349320u,
			512u,
			134217728u,
			134349312u,
			134217728u,
			131080u,
			520u,
			131072u,
			134349312u,
			134218240u,
			0u,
			512u,
			131080u,
			134349320u,
			134218240u,
			134217736u,
			512u,
			0u,
			134348808u,
			134218248u,
			131072u,
			134217728u,
			134349320u,
			8u,
			131592u,
			131584u,
			134217736u,
			134348800u,
			134218248u,
			520u,
			134348800u,
			131592u,
			8u,
			134348808u,
			131584u
		};

		private static uint[] aa = new uint[64]
		{
			8396801u,
			8321u,
			8321u,
			128u,
			8396928u,
			8388737u,
			8388609u,
			8193u,
			0u,
			8396800u,
			8396800u,
			8396929u,
			129u,
			0u,
			8388736u,
			8388609u,
			1u,
			8192u,
			8388608u,
			8396801u,
			128u,
			8388608u,
			8193u,
			8320u,
			8388737u,
			1u,
			8320u,
			8388736u,
			8192u,
			8396928u,
			8396929u,
			129u,
			8388736u,
			8388609u,
			8396800u,
			8396929u,
			129u,
			0u,
			0u,
			8396800u,
			8320u,
			8388736u,
			8388737u,
			1u,
			8396801u,
			8321u,
			8321u,
			128u,
			8396929u,
			129u,
			1u,
			8192u,
			8388609u,
			8193u,
			8396928u,
			8388737u,
			8193u,
			8320u,
			8388608u,
			8396801u,
			128u,
			8388608u,
			8192u,
			8396928u
		};

		private static uint[] ab = new uint[64]
		{
			256u,
			34078976u,
			34078720u,
			1107296512u,
			524288u,
			256u,
			1073741824u,
			34078720u,
			1074266368u,
			524288u,
			33554688u,
			1074266368u,
			1107296512u,
			1107820544u,
			524544u,
			1073741824u,
			33554432u,
			1074266112u,
			1074266112u,
			0u,
			1073742080u,
			1107820800u,
			1107820800u,
			33554688u,
			1107820544u,
			1073742080u,
			0u,
			1107296256u,
			34078976u,
			33554432u,
			1107296256u,
			524544u,
			524288u,
			1107296512u,
			256u,
			33554432u,
			1073741824u,
			34078720u,
			1107296512u,
			1074266368u,
			33554688u,
			1073741824u,
			1107820544u,
			34078976u,
			1074266368u,
			256u,
			33554432u,
			1107820544u,
			1107820800u,
			524544u,
			1107296256u,
			1107820800u,
			34078720u,
			0u,
			1074266112u,
			1107296256u,
			524544u,
			33554688u,
			1073742080u,
			524288u,
			0u,
			1074266112u,
			34078976u,
			1073742080u
		};

		private static uint[] ac = new uint[64]
		{
			536870928u,
			541065216u,
			16384u,
			541081616u,
			541065216u,
			16u,
			541081616u,
			4194304u,
			536887296u,
			4210704u,
			4194304u,
			536870928u,
			4194320u,
			536887296u,
			536870912u,
			16400u,
			0u,
			4194320u,
			536887312u,
			16384u,
			4210688u,
			536887312u,
			16u,
			541065232u,
			541065232u,
			0u,
			4210704u,
			541081600u,
			16400u,
			4210688u,
			541081600u,
			536870912u,
			536887296u,
			16u,
			541065232u,
			4210688u,
			541081616u,
			4194304u,
			16400u,
			536870928u,
			4194304u,
			536887296u,
			536870912u,
			16400u,
			536870928u,
			541081616u,
			4210688u,
			541065216u,
			4210704u,
			541081600u,
			0u,
			541065232u,
			16u,
			16384u,
			541065216u,
			4210704u,
			16384u,
			4194320u,
			536887312u,
			0u,
			541081600u,
			536870912u,
			4194320u,
			536887312u
		};

		private static uint[] ad = new uint[64]
		{
			2097152u,
			69206018u,
			67110914u,
			0u,
			2048u,
			67110914u,
			2099202u,
			69208064u,
			69208066u,
			2097152u,
			0u,
			67108866u,
			2u,
			67108864u,
			69206018u,
			2050u,
			67110912u,
			2099202u,
			2097154u,
			67110912u,
			67108866u,
			69206016u,
			69208064u,
			2097154u,
			69206016u,
			2048u,
			2050u,
			69208066u,
			2099200u,
			2u,
			67108864u,
			2099200u,
			67108864u,
			2099200u,
			2097152u,
			67110914u,
			67110914u,
			69206018u,
			69206018u,
			2u,
			2097154u,
			67108864u,
			67110912u,
			2097152u,
			69208064u,
			2050u,
			2099202u,
			69208064u,
			2050u,
			67108866u,
			69208066u,
			69206016u,
			2099200u,
			0u,
			2u,
			69208066u,
			0u,
			2099202u,
			69206016u,
			2048u,
			67108866u,
			67110912u,
			2048u,
			2097154u
		};

		private static uint[] ae = new uint[64]
		{
			268439616u,
			4096u,
			262144u,
			268701760u,
			268435456u,
			268439616u,
			64u,
			268435456u,
			262208u,
			268697600u,
			268701760u,
			266240u,
			268701696u,
			266304u,
			4096u,
			64u,
			268697600u,
			268435520u,
			268439552u,
			4160u,
			266240u,
			262208u,
			268697664u,
			268701696u,
			4160u,
			0u,
			0u,
			268697664u,
			268435520u,
			268439552u,
			266304u,
			262144u,
			266304u,
			262144u,
			268701696u,
			4096u,
			64u,
			268697664u,
			4096u,
			266304u,
			268439552u,
			64u,
			268435520u,
			268697600u,
			268697664u,
			268435456u,
			262144u,
			268439616u,
			0u,
			268701760u,
			262208u,
			268435520u,
			268697600u,
			268439552u,
			268439616u,
			0u,
			268701760u,
			266240u,
			266240u,
			4160u,
			4160u,
			262208u,
			268435456u,
			268701696u
		};

		public override void init(byte[] key, byte[] iv)
		{
			if (key != null || iv != null)
			{
				if (key.Length < 24)
				{
					throw new Exception("Key is too small");
				}
				Array.Copy(key, 0, field_f, 0, 8);
				Array.Copy(key, 8, field_g, 0, 8);
				Array.Copy(key, 16, field_h, 0, 8);
				field_p = true;
				return;
			}
			throw new Exception("Key is too small");
		}

		public override void setSessionKey(byte[] key, byte[] iv)
		{
			field_p = true;
			if (key != null || iv != null)
			{
				if (key.Length < 24)
				{
					throw new Exception("Key is too small");
				}
				Array.Copy(key, 0, field_f, 0, 8);
				Array.Copy(key, 8, field_g, 0, 8);
				Array.Copy(key, 16, field_h, 0, 8);
			}
			else if (field_f == null)
			{
				throw new Exception("Key is too small");
			}
		}

		public override byte[] decrypt(byte[] ebuffer)
		{
			return decrypt(ebuffer, ebuffer.Length);
		}

		public override byte[] decrypt(byte[] ebuffer, int length)
		{
			int num = length;
			byte b = ebuffer[num - 1];
			if (b < 0 || b > 8)
			{
				return null;
			}
			int num2 = num - b;
			byte[] array = new byte[num - 1];
			num--;
			if (field_p)
			{
				a(field_h, field_g, field_f, (byte)1);
			}
			for (int i = 0; i < num; i += 8)
			{
				byte[] array2 = new byte[8];
				Array.Copy(ebuffer, i, array2, 0, 8);
				Array.Copy(a(array2, 1), 0, array, i, 8);
			}
			byte[] array3 = new byte[num2];
			Array.Copy(array, 0, array3, 0, num2);
			return array3;
		}

		public override byte[] encrypt(byte[] buffer)
		{
			return encrypt(buffer, buffer.Length);
		}

		public override byte[] encrypt(byte[] buffer, int len)
		{
			byte b = (byte)((len % 8 != 0) ? (8 - len % 8) : 0);
			int num = len + b;
			byte[] array = new byte[num + 1];
			if (field_p)
			{
				a(field_f, field_g, field_h, (byte)0);
			}
			for (int i = 0; i < len; i += 8)
			{
				byte[] array2 = new byte[8];
				if (i > len - 8)
				{
					Array.Copy(buffer, i, array2, 0, len & 7);
				}
				else
				{
					Array.Copy(buffer, i, array2, 0, 8);
				}
				Array.Copy(a(array2, 0), 0, array, i, 8);
			}
			array[num] = (byte)(b + 1);
			return array;
		}

		public override int maxDelta()
		{
			return 8;
		}

		internal new void a(byte[] A_0, byte[] A_1, byte[] A_2, byte A_3)
		{
			field_i = b(A_0, A_3);
			field_j = b(A_1, (byte)((A_3 == 0) ? 1 : 0));
			field_k = b(A_2, A_3);
			field_l = b(A_0, A_3);
			field_m = b(A_1, (byte)((A_3 == 0) ? 1 : 0));
			field_n = b(A_2, A_3);
			Array.Copy(w, 0, field_o, 0, 8);
			field_p = false;
		}

		internal uint[] b(byte[] A_0, byte A_1)
		{
			byte[] array = new byte[56];
			byte[] array2 = new byte[56];
			uint[] array3 = new uint[32];
			for (int i = 0; i < 56; i++)
			{
				int num = t[i];
				int num2 = num & 7;
				array[i] = (byte)(((A_0[num >> 3] & field_r[16 + num2]) != 0) ? 1u : 0u);
			}
			for (int j = 0; j < 16; j++)
			{
				int num2 = ((A_1 != 1) ? (j << 1) : (15 - j << 1));
				int num3 = num2 + 1;
				array3[num2] = (array3[num3] = 0u);
				for (int i = 0; i < 28; i++)
				{
					int num = i + u[j];
					if (num < 28)
					{
						array2[i] = array[num];
					}
					else
					{
						array2[i] = array[num - 28];
					}
				}
				for (int i = 28; i < 56; i++)
				{
					int num = i + u[j];
					if (num < 56)
					{
						array2[i] = array[num];
					}
					else
					{
						array2[i] = array[num - 28];
					}
				}
				for (int i = 0; i < 24; i++)
				{
					if (array2[v[i]] != 0)
					{
						array3[num2] |= s[i];
					}
					if (array2[v[i + 24]] != 0)
					{
						array3[num3] |= s[i];
					}
				}
			}
			return a(array3);
		}

		private new uint[] a(uint[] A_0)
		{
			uint[] array = new uint[32];
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			while (num < 16)
			{
				num2 = num3++;
				array[num4] = (A_0[num2] & 0xFC0000) << 6;
				array[num4] |= (A_0[num2] & 0xFC0) << 10;
				array[num4] |= (A_0[num3] & 0xFC0000) >> 10;
				array[num4] |= (A_0[num3] & 0xFC0) >> 6;
				num4++;
				array[num4] = (A_0[num2] & 0x3F000) << 12;
				array[num4] |= (A_0[num2] & 0x3F) << 16;
				array[num4] |= (A_0[num3] & 0x3F000) >> 4;
				array[num4] |= A_0[num3] & 0x3F;
				num4++;
				num++;
				num3++;
			}
			return array;
		}

		private new byte[] a(byte[] A_0, byte A_1)
		{
			byte[] array = new byte[8];
			if (A_1 != 0)
			{
				byte[] array2 = new byte[8];
				Array.Copy(A_0, 0, array2, 0, 8);
				a(A_0, field_l);
				a(A_0, field_m);
				a(A_0, field_n);
				a(array, field_o, A_0, 2);
				Array.Copy(array2, 0, field_o, 0, 8);
			}
			else
			{
				a(array, field_o, A_0, 2);
				a(array, field_i);
				a(array, field_j);
				a(array, field_k);
				Array.Copy(array, 0, field_o, 0, 8);
			}
			return array;
		}

		internal new void a(byte[] A_0, byte[] A_1, byte[] A_2, int A_3)
		{
			switch (A_3)
			{
			case 2:
			{
				for (int i = 0; i < 8; i++)
				{
					A_0[i] = (byte)(A_1[i] ^ A_2[i]);
				}
				break;
			}
			case 1:
			{
				for (int i = 0; i < 8; i++)
				{
					A_0[i] = (byte)(A_1[i] & A_2[i]);
				}
				break;
			}
			}
		}

		internal new void a(byte[] A_0, uint[] A_1)
		{
			uint[] array = new uint[2];
			b(A_0, array);
			a(array, A_1);
			a(array, A_0);
		}

		internal void b(byte[] A_0, uint[] A_1)
		{
			int num = 0;
			A_1[0] = (uint)((A_0[num] & 0xFF) << 24);
			num++;
			A_1[0] |= (uint)((A_0[num] & 0xFF) << 16);
			num++;
			A_1[0] |= (uint)((A_0[num] & 0xFF) << 8);
			num++;
			A_1[0] |= (uint)(A_0[num] & 0xFF);
			num++;
			A_1[1] = (uint)((A_0[num] & 0xFF) << 24);
			num++;
			A_1[1] |= (uint)((A_0[num] & 0xFF) << 16);
			num++;
			A_1[1] |= (uint)((A_0[num] & 0xFF) << 8);
			num++;
			A_1[1] |= (uint)(A_0[num] & 0xFF);
		}

		internal new void a(uint[] A_0, byte[] A_1)
		{
			int num = 0;
			A_1[num] = (byte)((A_0[0] >> 24) & 0xFFu);
			num++;
			A_1[num] = (byte)((A_0[0] >> 16) & 0xFFu);
			num++;
			A_1[num] = (byte)((A_0[0] >> 8) & 0xFFu);
			num++;
			A_1[num] = (byte)(A_0[0] & 0xFFu);
			num++;
			A_1[num] = (byte)((A_0[1] >> 24) & 0xFFu);
			num++;
			A_1[num] = (byte)((A_0[1] >> 16) & 0xFFu);
			num++;
			A_1[num] = (byte)((A_0[1] >> 8) & 0xFFu);
			num++;
			A_1[num] = (byte)(A_0[1] & 0xFFu);
		}

		internal new void a(uint[] A_0, uint[] A_1)
		{
			int num = 0;
			uint num2 = A_0[0];
			uint num3 = A_0[1];
			uint num4 = ((num2 >> 4) ^ num3) & 0xF0F0F0Fu;
			num3 ^= num4;
			num2 ^= num4 << 4;
			num4 = ((num2 >> 16) ^ num3) & 0xFFFFu;
			num3 ^= num4;
			num2 ^= num4 << 16;
			num4 = ((num3 >> 2) ^ num2) & 0x33333333u;
			num2 ^= num4;
			num3 ^= num4 << 2;
			num4 = ((num3 >> 8) ^ num2) & 0xFF00FFu;
			num2 ^= num4;
			num3 ^= num4 << 8;
			num3 = ((num3 << 1) | ((num3 >> 31) & 1u)) & 0xFFFFFFFFu;
			num4 = (num2 ^ num3) & 0xAAAAAAAAu;
			num2 ^= num4;
			num3 ^= num4;
			num2 = ((num2 << 1) | ((num2 >> 31) & 1u)) & 0xFFFFFFFFu;
			for (int i = 0; i < 8; i++)
			{
				num4 = (num3 << 28) | (num3 >> 4);
				_ = A_1[num];
				num4 ^= A_1[num];
				num++;
				uint num5 = ad[num4 & 0x3F];
				num5 |= ab[(num4 >> 8) & 0x3F];
				num5 |= z[(num4 >> 16) & 0x3F];
				num5 |= x[(num4 >> 24) & 0x3F];
				num4 = num3 ^ A_1[num];
				num++;
				num5 |= ae[num4 & 0x3F];
				num5 |= ac[(num4 >> 8) & 0x3F];
				num5 |= aa[(num4 >> 16) & 0x3F];
				num5 |= y[(num4 >> 24) & 0x3F];
				num2 ^= num5;
				num4 = (num2 << 28) | (num2 >> 4);
				num4 ^= A_1[num];
				num++;
				num5 = ad[num4 & 0x3F];
				num5 |= ab[(num4 >> 8) & 0x3F];
				num5 |= z[(num4 >> 16) & 0x3F];
				num5 |= x[(num4 >> 24) & 0x3F];
				num4 = num2 ^ A_1[num];
				num++;
				num5 |= ae[num4 & 0x3F];
				num5 |= ac[(num4 >> 8) & 0x3F];
				num5 |= aa[(num4 >> 16) & 0x3F];
				num5 |= y[(num4 >> 24) & 0x3F];
				num3 ^= num5;
			}
			num3 = (num3 << 31) | (num3 >> 1);
			num4 = (num2 ^ num3) & 0xAAAAAAAAu;
			num2 ^= num4;
			num3 ^= num4;
			num2 = (num2 << 31) | (num2 >> 1);
			num4 = ((num2 >> 8) ^ num3) & 0xFF00FFu;
			num3 ^= num4;
			num2 ^= num4 << 8;
			num4 = ((num2 >> 2) ^ num3) & 0x33333333u;
			num3 ^= num4;
			num2 ^= num4 << 2;
			num4 = ((num3 >> 16) ^ num2) & 0xFFFFu;
			num2 ^= num4;
			num3 ^= num4 << 16;
			num4 = ((num3 >> 4) ^ num2) & 0xF0F0F0Fu;
			num2 ^= num4;
			num3 = (A_0[0] = num3 ^ (num4 << 4));
			A_0[1] = num2;
		}
	}
}
